<?php

namespace Xrfg\Wallet\ETH\Console;

use App\Models\Account;
use App\Models\Device;
use Exception;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
use phpseclib\Math\BigInteger;
use App\Models\Recharge as RechargeModel;
use Xrfg\Wallet\Common\Jobs\RechargeJob;
use Xrfg\Wallet\ETH\Services\ETHWallet;
use Xrfg\Wallet\ETH\Traits\ETHHelper;

class RechargeERC20 extends Command
{
    use ETHHelper;

    protected $signature = 'recharge:erc20';

    protected $description = 'ERC20 充值';

    protected $times = 0;

    protected $rpc;

    protected $config;

    protected $blockNumber;

    public function __construct()
    {
        parent::__construct();
        $this->config = config('wallet.eth');
        $this->rpc = new ETHWallet($this->config['node']['rpc']);
    }

    public function handle()
    {
        ++$this->times;
        if ($this->times >= 100) {
            return;
        }
        $this->info('times:'.$this->times);
        $this->blockNumber = Cache::get('ERC20:blockNumber', 10450154);
        sleep(1);
        try {
            $result = $this->rpc->eth_blockNumber();
            $blockNumber = new BigInteger($result, 16);
            $this->info('latest:'.$blockNumber->toString());
            if ($blockNumber->toString() - 12 <= $this->blockNumber) {
                self::handle();

                return;
            }
            $this->info('current:'.$this->blockNumber);
            $this->info('scanning:'.($this->blockNumber + 1));
            $fromBlock =
            $toBlock = self::num2hex($this->blockNumber + 1);
            $address = $address = array_keys($this->config['contracts']);
            $topics = ['0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef'];

            $logs = $this->rpc->eth_getLogs(compact('fromBlock', 'toBlock', 'address', 'topics'));
            collect($logs)->each(function ($log) {
                $coinId = $this->config['contracts'][$log['address']]['id'];
                $hash = $log['transactionHash'];
                $address = '0x'.substr($log['topics'][2], 26);
                $number = self::wei2ether($log['data'], $this->config['contracts'][$log['address']]['decimals']);
                $isAccountExists = Account::where('coin_id', $coinId)
                    ->where('address', $address)
                    ->exists();
                // 检查地址
                if ($isAccountExists) {
                    $isRechargeExists = RechargeModel::where('hash', $hash)->exists();
                    // 检查hash
                    if (!$isRechargeExists) {
                        RechargeJob::dispatch($coinId, $hash, $number, $address)
                            ->onQueue('recharge');
                    }
                }
            });
            Cache::forever('ERC20:blockNumber', $this->blockNumber + 1);
            self::handle();
        } catch (Exception $exception) {
            Log::error($exception);
            self::handle();
        }
    }
}
